package org.finesys.common.security.core.service;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import org.finesys.common.constants.BaseConstant;
import org.finesys.common.constants.SecurityConstants;
import org.finesys.common.core.module.R;
import org.finesys.common.core.module.ROpt;
import org.finesys.common.security.core.module.AuthUser;
import org.finesys.system.api.dto.UserInfo;
import org.finesys.system.api.entity.SysUser;
import org.springframework.beans.BeanUtils;
import org.springframework.core.Ordered;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.*;

/**
 * 用户信息获取
 */
public interface AuthUserService extends UserDetailsService, Ordered {

    /**
     * 是否支持此客户端校验
     *
     * @param clientId  目标客户端
     * @param grantType 授权方式
     * @return true/false
     */
    default boolean support(String clientId, String grantType) {
        return true;
    }

    /**
     * 排序值 默认取最大的
     *
     * @return 排序值
     */
    @Override
    default int getOrder() {
        return 0;
    }

    /**
     * 构建userdetails
     *
     * @param result 用户信息
     * @return UserDetails
     */
    default UserDetails getUserDetails(R<UserInfo> result) {
        UserInfo userInfo = ROpt.ofNullable(result).getData().orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        Set<String> dbAuthsSet = new HashSet<>();
        if (ArrayUtil.isNotEmpty(userInfo.getRoles())) {
            // 获取角色
            Arrays.stream(userInfo.getRoles()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
            // 获取资源
            dbAuthsSet.addAll(Arrays.asList(userInfo.getPermissions()));
        }
        Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
        SysUser sysUser = userInfo.getSysUser();
        boolean enabled = true;
        boolean accountNonExpired = true;
        //增加账户是否过期
        Date passwordExpireDate = sysUser.getPasswordExpireDate();
        if (passwordExpireDate != null) {
            Date thisDate = new Date();
            if (passwordExpireDate.before(thisDate)) {
                accountNonExpired = false;
            }
        }
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = StrUtil.equals(sysUser.getStatus(), BaseConstant.STATUS_VALID);
        AuthUser authUser = new AuthUser(sysUser.getUsername(), sysUser.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        BeanUtils.copyProperties(sysUser, authUser);
        //密码的加密方式
        return authUser;
    }

    /**
     * 通过用户信息查找
     */
    default UserDetails loadUserByAuthUser(AuthUser authUser) {
        return this.loadUserByUsername(authUser.getUsername());
    }
}
